<?php
/**
 * CompleXml Framework
 *
 * @category   CompleXml
 * @package    CompleXml_View
 * @copyright  Copyright (c) 2008 Andrey Kucherenko
 * @license    New BSD License
 * @version    $Id: View.php 9 2008-11-16 17:58:08Z kucherenko.andrey $
 */


class CompleXml_View extends XMLWriter
{
	const MESSAGE_ERROR = 'error';

	const MESSAGE_INFO = 'info';

	const MESSAGE_DEBUG = 'debug';

	protected static $_messages = array(

	);

	private $_is_init = false;

	private $_locale;

	/**
	 * Default name for uncorect node name
	 *
	 * @var string
	 */
	private $_default_node_name = 'row';
	/**
	 * Default name for uncorect attribute name
	 *
	 * @var string
	 */
	private $_default_attribute_name = 'attr';

	/**
	 * Path to template
	 * @var string
	 */
	private $_template_path = null;

	public function __construct ($encoding = 'utf-8')
	{
		$this->openMemory();
		$this->startDocument('1.0', $encoding);
	}

	public function init($document='page', $content = 'content')
	{
		$this->_is_init = true;
		$this->startElement($document);
		if (!is_null($content)){
			$this->startElement($content);
		}

	}

	public function getXml()
	{
		$this->writeElement('messages', self::$_messages);
		$this->endElement();
		$this->writeElement('locale', $this->getLocale());
		$this->endElement();
		return $this->outputMemory();
	}

	public function getMessages()
	{
		return self::$_messages;
	}

	public function addMessage($message, $type)
	{
		self::$_messages[] = array(
            'type' => $type , 'message' => $message
		);
	}

	public function setMessages(array $messages)
	{
		self::$_messages = $messages;
	}

	public function addError ($message)
	{
		$this->addMessage($message, CompleXml_View::MESSAGE_ERROR);
	}

	public function addInfo ($message)
	{
		$this->addMessage($message, CompleXml_View::MESSAGE_INFO);
	}

	/**
	 * @return string
	 */
	public function getLocale ()
	{
		return $this->_locale;
	}
	/**
	 * @param string $locale
	 */
	public function setLocale ($locale)
	{
		$this->_locale = $locale;
	}

	public function setTemplate($path)
	{
		$this->_template_path = $path;
	}
	/**
	 * @return string
	 */
	public function getTemplate()
	{
		return $this->_template_path;
	}
	/**
	 * @return string
	 */
	public function getDefaultAttributeName ()
	{
		return $this->_default_attribute_name;
	}
	/**
	 * @return string
	 */
	public function getDefaultNodeName ()
	{
		return $this->_default_node_name;
	}
	/**
	 * @param string $default_attribute_name
	 */
	public function setDefaultAttributeName ($default_attribute_name)
	{
		$this->_default_attribute_name = $default_attribute_name;
	}
	/**
	 * @param string $default_node_name
	 */
	public function set_default_node_name ($default_node_name)
	{
		$this->_default_node_name = $default_node_name;
	}
	public function __set ($name, $value)
	{
		$this->writeElement($name, $value);
	}
	public function writeElement ($name, $value = null, $attributes = null)
	{
		if ($value instanceof Iterator || is_array($value)|| $value instanceof IteratorAggregate) {
			$this->startElement($name);
			$this->writeAttribute('attr', $attributes);
			$this->_createXml($value);
			$this->endElement();
		} else {
			if (! is_null($value)) {
				if (empty($attributes)){
					parent::writeElement($name, $value);
				}else{
					parent::startElement($name);
					$this->writeAttribute('attr', $attributes);
					parent::text($value);
					parent::endElement();
				}
			}
		}
	}
	public function writeElementNs ($prefix, $name, $uri, $value = null, $attributes = null)
	{
		if ($value instanceof Iterator || is_array($value) || $value instanceof IteratorAggregate) {
			$this->startElementNs($prefix, $name, $uri);
			if (! is_null($attributes)) {
				$this->writeAttribute('attr', $attributes);
			}
			$this->_createXml($value);
			$this->endElement();
		} else {
			parent::writeElementNs($prefix, $name, $uri, $value);
		}
	}
	public function writeAttribute ($name, $value)
	{
		if ($value instanceof Iterator || is_array($value) || $value instanceof IteratorAggregate) {
			$i = 0;
			foreach ($value as $key => $val) {
				if (! is_string($key[ 0 ])) {
					parent::writeAttribute($this->getDefaultAttributeName() . $i, $val);
				} else {
					parent::writeAttribute($key, $val);
				}
				$i ++;
			}
		} else {
			parent::writeAttribute($name, $value);
		}
	}
	/**
	 * Generate xi:include instruction
	 *
	 * @param string $path
	 */
	public function includeXML ($path)
	{
		$this->startElementNs('xi', 'include', 'http://www.w3.org/2001/XInclude');
		$this->writeAttribute('href', $path);
		$this->writeAttribute('parse', 'xml');
		$this->startElementNs('xi', 'fallback', 'http://www.w3.org/2001/XInclude');
		$this->writeElement('error', 'xinclude: ' . $path . ' not found');
		$this->endElement();
		$this->endElement();
	}
	protected function _createXml ($object)
	{
		$i = 0;
		foreach ($object as $key => $value) {
			if (! is_string($key[ 0 ])) {
				$this->writeElement($this->getDefaultNodeName(), $value, array(
				$this->getDefaultNodeName() . '_id' => $i
				));
			} else {
				$this->writeElement($key, $value);
			}
			$i ++;
		}
	}
}